1. /* sdfdsmul.cpp by K.Tsuru */
  2. // function ID = 324 DRADIX
  3. /*******************************
  4. SDouble class
  5. m*n 0 <= n < ULONG_MAX/radix
  6. (long decimal)*(short integer)
  7. *********************************/
  8. #ifndef SN_H
  9. #include "sn.h"
  10. #endif
  11. SDouble DsMult(const SDouble& m, ulong n){
  12. RealSize C;
  13. ulong rdx = m.Radix(), mt = m.SlOpMaxValue();
  14. //In the SDecimal class let "x *= 2;", etc. be an error.
  15. //Must use "XsMult(x, 2, x);" to get high speed.
  16. if(rdx != DRADIX) m.SetError(m.RADIX_ERR, "Use XsMult", 324);
  17. if(n > mt) m.SetError(m.OUT_OF_RANGE,"DsMult", 324);
  18. int sgn = m.SNSign(); //It does not use "Sign()".
  19. //Maybe it contributes to effective figures.
  20. int shift = 0, ch_fe = 0;
  21. if(!n || !sgn) return SDZero(m);
  22. else if(n == 1) return m;
  23. ulong w;
  24. if( m.First() <= 2){ // m(i)*n < R*n < ULONG_MAX < R^3
  25. //By first two figures it predicts that a carry to top figure causes or not.
  26. //This needs in the fixed point mode too.
  27. w = (ulong)m.figure(1)*n + ( (ulong)m.figure(2)*n )/rdx;
  28. if( w >= m.RadixSq() ) shift = 2; // w < ULONG_MAX(1+1/R) < R^3
  29. else if(w >= rdx) shift = 1;
  30. }
  31. uint cur_max_sz = m.CurrentMaxSize();
  32. int last = (int)min(m.Last(), cur_max_sz - 1);
  33. // m.Last() > cur_max_sz for Pi() etc.
  34. /*
  35. When 'n' is large it is necessary to increase the effective figures to avoid
  36. a computational error.
  37. */
  38. uint rsize;
  39. if( m.IsPointFixed() ) rsize = m.figure.size() + (uint)shift;
  40. else rsize = m.Last()+ (uint)shift + 2u;
  41. if(rsize >= cur_max_sz) rsize = cur_max_sz;
  42. if(last + shift >= (int)cur_max_sz){
  43. C.SetEffFig(m.EffFig() + (uint)shift + 1, C.TEMP_EXTEND);
  44. rsize += (uint)shift;
  45. ch_fe = 1;
  46. }
  47. SDouble result;
  48. result.valloc(rsize, 0);
  49. result.SetSign(sgn); result.rdxExp = m.rdxExp + shift;
  50. int mf = (int)m.First(), i;
  51. ulong u = 0; //carry
  52. if( ( (last+1) < (int)m.figure.size() ) && m[last+1] ){ //over effective figures
  53. u = (ulong)m.figure(last+1)*n; //contribution from lower part
  54. u /= rdx;
  55. }
  56. #ifndef NDEBUG
  57. m.figure(last); result.figure(last+shift);
  58. #endif
  59. const fType* mv = m.ReadFigures();
  60. fType* rv = result.figure.Elements();
  61. if(shift){
  62. for(i = last ; i >= mf; i--){
  63. w = mv[i]*n + u;
  64. u = w/rdx; //carry
  65. rv[i+shift] = fType(w - u*rdx); // = w%rdx
  66. }
  67. } else { // shift = 0
  68. for(i = last ; i >= mf; i--){
  69. w = mv[i]*n + u;
  70. u = w/rdx; // carry
  71. rv[i] = fType(w - u*rdx); // = w%rdx
  72. }
  73. }
  74. mf = i+shift;
  75. #ifndef NDEBUG
  76. assert(i>=0); result.figure(mf);
  77. #endif
  78. if(u >= rdx){ // w = u, m.figures() = 0
  79. while(u && (mf >= 0)){ //a few times
  80. rv[mf] = fType(u%rdx);
  81. u /= rdx; // mf - 1 >= 1
  82. mf--;
  83. }
  84. if(mf < 0) mf = 0;
  85. }else result.figure[mf] = (fType)u; //carry to the highest figure
  86. //It detects figure position.
  87. while(!rv[mf]) mf++;
  88. result.aTail = (uint)mf;
  89. last += shift;
  90. #ifndef NDEBUG
  91. result.figure(last);
  92. #endif
  93. while(!rv[last]) last--;
  94. result.aHead = (uint)last;
  95. if(ch_fe) C.SetEffFig(0);
  96. //It disposes of the carry to the 'figure[0]' , etc.
  97. result.Reform(324);
  98. return result;
  99. }

sdfdsmul.cpp : last modifiled at 2017/07/17 14:52:20(3,117 bytes)
created at 2017/10/07 10:22:50
The creation time of this html file is 2017/10/07 11:29:39 (Sat Oct 07 11:29:39 2017).